#include <Eigen/Core>
#include <Eigen/Dense>
#include <algorithm>
#include <chrono>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <vector>

#include "hungarian_optimizer.h"
#include "hungarian_test.h"

using namespace std;

int main() {
  std::vector<std::vector<int>> nb_graph = {{4, 5}, {6}, {6, 7}, {4},
                                            {0, 3}, {0}, {1, 2}, {2}};
  std::vector<std::vector<int>> components;

  ConnectedComponentAnalysis(nb_graph, components);

  printMatrix(components);

  std::function<bool(int)> is_valid_cost;
  is_valid_cost = std::bind1st(std::greater<int>(), 10);
  cout << is_valid_cost(2) << endl << endl;

  vector<vector<int>> costs_(256, vector<int>(256, 0));
  for (int i = 0; i < 256; ++i) {
    for (int j = 0; j < 256; ++j) {
      costs_[i][j] = static_cast<int>(rand() % 256 + 1);
    }
  }
  // vector<vector<int>> costs_ = {{90, 75, 75, 80},
  //                               {35, 85, 55, 65},
  //                               {125, 95, 90, 105},
  //                               {45, 110, 95, 115}};

  // vector<vector<int>> costs_ = {{1, 2, 3}, {2, 4, 6}, {3, 6, 9}};

  HungarianOptimizer<int> optimizer_;
  optimizer_.costs(costs_);


  chrono::steady_clock::time_point t1 = chrono::steady_clock::now();

  std::vector<std::pair<size_t, size_t>> assignments;
  optimizer_.Minimize(&assignments);

  chrono::steady_clock::time_point t2 = chrono::steady_clock::now();
  chrono::duration<double> time_used =
      chrono::duration_cast<chrono::duration<double>>(t2 - t1);
  cout << "solve time cost = " << time_used.count() << " seconds. " << endl;

  // for(size_t i = 0; i < assignments.size(); ++i)
  //   cout << assignments[i].first << " " << assignments[i].second << endl;

  return 0;
}
